home *** CD-ROM | disk | FTP | other *** search
- /* This program reads a set of 3D points from a file and
- then displays them in a window where they can be rotated
- around left-right and up-down.
-
- This version is only for the Power Macintosh.
- It assumes System 7.1.2.
-
- It gives examples of using the required apple events,
- file dropping, and reading c-style from an FSS record.
-
- The rotation code is from the NewSpaceShuttle source.
- This code and program, as far as they are able to be,
- are in the public domain.
-
- Craig Kloeden <craig@raru.adelaide.edu.au>
- 9 June 1994
- */
-
- #include <QDOffscreen.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <EPPC.h>
- #include <AppleEvents.h>
-
- #define MaxPoints 2500
- #define PI 3.141592653589793
- #define PI2 6.283185307179586
-
- void main (void);
- void init (void);
- void HandleEvent (void);
- void HandleMouseDown (EventRecord *theEvent);
- void HandleMenu (long mSelect);
- void finishup (void);
- void mousepress (Point p);
- void rotate (void);
- void getuserfile (void);
- void readfile (short refnum, long parid, Str63 name);
- void installAEhandlers (void);
- void DoHighLevelEvent (EventRecord *theEvent);
- pascal OSErr openAE (AppleEvent *theEvent, AppleEvent *reply, long refcon);
- pascal OSErr quitAE (AppleEvent *theEvent, AppleEvent *reply, long refcon);
- pascal OSErr printAE (AppleEvent *theEvent, AppleEvent *reply, long refcon);
- pascal OSErr startAE (AppleEvent *theEvent, AppleEvent *reply, long refcon);
- void died (char desc[255], int code, int ref);
-
- double Xangle, Yangle, Zangle;
- double aaa[MaxPoints][3];
- int cc[MaxPoints];
- int N;
- double DD = 120;
- Boolean done;
- Rect frameRect, dragRect;
- CWindowPtr thewindow;
- GWorldPtr drawWorldP;
- PixMapHandle thePixMapH, windowPixMapH;
- PixMapPtr drawPixMapP, windowPixMapP;
- MenuHandle applemenu, filemenu, editmenu, optionmenu;
- GWorldPtr saveWorld;
- GDHandle saveDevice;
- OSErr err;
- RGBColor black = {0,0,0}, white = {65535, 65535, 65535};
- RGBColor red = {65535, 0, 0}, green = {0, 65535, 0}, blue = {0, 0, 65535};
-
- //************************************************************************
-
- void main (void)
- {
- init ();
-
- done = false;
- while (! done)
- {
- HandleEvent();
- }
-
- finishup ();
- }
-
- //************************************************************************
-
- void init (void)
- {
- EventRecord tempEvent;
-
- /* Initialize Managers */
- InitGraf (&qd.thePort);
- InitFonts ();
- FlushEvents(everyEvent - osMask - diskMask, 0);
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (nil);
- InitCursor ();
- MaxApplZone();
- MoreMasters();
-
- EventAvail(everyEvent, &tempEvent);
- EventAvail(everyEvent, &tempEvent);
- EventAvail(everyEvent, &tempEvent);
-
- /* set up menus */
- applemenu = GetMenu(128);
- if (applemenu == NULL) died ("Can't find Apple Menu Resource", 0, 001);
- AddResMenu(applemenu, 'DRVR');
- filemenu = GetMenu(129);
- editmenu = GetMenu(130);
- optionmenu = GetMenu(131);
- InsertMenu(applemenu, 0);
- InsertMenu(filemenu, 0);
- InsertMenu(editmenu, 0);
- InsertMenu(optionmenu, 0);
- DrawMenuBar();
-
- dragRect = qd.screenBits.bounds;
- SetRect (&frameRect, 0, 0, 400, 400);
-
- /* because this is PPC only we dont have to check for old
- systems or the GWorld stuff :-)
- */
-
- /* set up the main window */
- thewindow = (CWindowPtr) GetNewCWindow (400, nil, (WindowPtr)-1L);
- if (thewindow == NULL) died ("Can't get Window Resource", 0, 002);
- SetPort ((WindowPtr)thewindow);
- GetGWorld(&saveWorld, &saveDevice);
- windowPixMapH = GetGWorldPixMap(saveWorld);
- HLockHi((Handle)windowPixMapH);
- LockPixels(windowPixMapH);
- windowPixMapP = *thewindow->portPixMap;
-
- /* set up offscreen GWorld */
- err = NewGWorld(&drawWorldP, 8, &frameRect, nil, nil, 0);
- if (err) died ("Could not Create GWorld", err, 003);
- thePixMapH = GetGWorldPixMap(drawWorldP);
- HLockHi((Handle)thePixMapH);
- LockPixels(thePixMapH);
- drawPixMapP = *thePixMapH;
-
- /* clear the GWorld */
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- SetGWorld(saveWorld, saveDevice);
-
- /* no points yet */
- N = 0;
-
- installAEhandlers ();
- }
-
- //************************************************************************
-
- void HandleEvent(void)
- {
- EventRecord theEvent;
-
- HiliteMenu(0);
-
- if (WaitNextEvent (everyEvent, &theEvent, 40, NULL))
- switch (theEvent.what)
- {
- case mouseDown:
- HandleMouseDown(&theEvent);
- break;
-
- case keyDown:
- if ((theEvent.modifiers & cmdKey) != 0)
- {
- HandleMenu(MenuKey((char) (theEvent.message & charCodeMask)));
- }
- break;
-
- case updateEvt:
- BeginUpdate((WindowPtr)thewindow);
- /* copy GWorld to screen window */
- SetGWorld(saveWorld, saveDevice);
- CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
- &frameRect, &frameRect, srcCopy, nil);
- EndUpdate((WindowPtr)thewindow);
- break;
-
- case activateEvt:
- InvalRect(&thewindow->portRect);
- break;
-
- case osEvt:
- if (theEvent.message & 1) /* Resume Event */
- {
- InitCursor();
- }
- else /* Suspend Event */
- {
- InitCursor();
- }
- break;
-
- case kHighLevelEvent:
- DoHighLevelEvent (&theEvent);
- break;
- }
- }
-
- //************************************************************************
-
- void HandleMouseDown (EventRecord *theEvent)
- {
- WindowPtr awindow;
- int windowCode = FindWindow (theEvent->where, &awindow);
-
- switch (windowCode)
- {
- case inSysWindow:
- SystemClick (theEvent, awindow);
- break;
-
- case inMenuBar:
- HandleMenu(MenuSelect(theEvent->where));
- break;
-
- case inDrag:
- if (awindow == (WindowPtr)thewindow)
- DragWindow((WindowPtr)thewindow, theEvent->where, &dragRect);
- break;
-
- case inContent:
- if (awindow == (WindowPtr)thewindow)
- {
- if (awindow != FrontWindow())
- SelectWindow((WindowPtr)thewindow);
- else
- {
- GlobalToLocal(&theEvent->where);
- mousepress (theEvent->where);
- }
- }
- break;
-
- case inGoAway:
- if (awindow == (WindowPtr)thewindow &&
- TrackGoAway((WindowPtr)thewindow, theEvent->where))
- {
- HideWindow ((WindowPtr)thewindow);
- N = 0;
- }
- break;
- }
- }
-
- //************************************************************************
-
- void HandleMenu (long mSelect)
- {
- int menuID = HiWord(mSelect);
- int menuItem = LoWord(mSelect);
- Str255 name;
- GrafPtr savePort;
- unsigned long ticks;
-
- switch (menuID)
- {
- case 128: /* apple menu */
- if (menuItem == 1) /* About */
- {
- Alert(128,NULL);
- break;
- }
- /* system apple menu item */
- GetPort(&savePort);
- GetItem(applemenu, menuItem, name);
- OpenDeskAcc(name);
- SetPort(savePort);
- break;
-
- case 129: /* file menu */
- switch (menuItem)
- {
- case 1: /* open */
- getuserfile();
- break;
- case 3: /* quit */
- done = true;
- break;
- }
- break;
-
- case 131: /* option menu */
- switch (menuItem)
- {
- case 1: /* perspective */
- if (DD == 120)
- {
- CheckItem (optionmenu, 1, FALSE);
- DD = 100000;
- }
- else
- {
- CheckItem (optionmenu, 1, TRUE);
- DD = 120;
- }
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- rotate ();
- SetGWorld(saveWorld, saveDevice);
- CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
- &frameRect, &frameRect, srcCopy, nil);
- break;
- case 3: /* rotate slow*/
- while (! Button())
- {
- ticks = TickCount();
- Yangle++;
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- rotate ();
- SetGWorld(saveWorld, saveDevice);
- while (TickCount() < ticks + 1) {}
- CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
- &frameRect, &frameRect, srcCopy, nil);
- }
- break;
- case 4: /* rotate fast*/
- while (! Button())
- {
- ticks = TickCount();
- Yangle += 2;
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- rotate ();
- SetGWorld(saveWorld, saveDevice);
- while (TickCount() < ticks + 1) {}
- CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
- &frameRect, &frameRect, srcCopy, nil);
- }
- break;
- }
- break;
- }
- }
-
- //************************************************************************
-
- void finishup (void) /* get outa here */
- {
- ExitToShell();
- }
-
- //************************************************************************
-
- void mousepress (Point p)
- {
- Point p1;
- int x, y, x1, y1;
- double sx, sy, sz;
-
- /* save original rotation angles */
- sx = Xangle;
- sy = Yangle;
- sz = Zangle;
-
- x1 = 0;
- y1 = 0;
-
- while (StillDown()) /* loop while button held down */
- {
- GetMouse (&p1);
- x = p.v - p1.v;
- y = p.h - p1.h;
-
- if (x != x1 || y != y1) /* if mouse moved since last time around */
- {
- Xangle = sx - x;
- Yangle = sy + y;
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- rotate ();
- SetGWorld(saveWorld, saveDevice);
- CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
- &frameRect, &frameRect, srcCopy, nil);
- x1 = x;
- y1 = y;
- }
- }
- }
-
- //************************************************************************
-
- void rotate ()
- {
- int Ec;
- double XV, YV, ZV, X, Y, Z, X3, Y3, Z3;
- double CB, SB, CH, SH, CP, SP;
- double AM, BM, CM, DM, EM, FM, GM, HM, IM;
- int XX, YY;
- double P, B, H;
-
- P = PI2 * Xangle / 360 - PI;
- B = PI2 * Zangle / 360;
- H = PI2 * Yangle / 360;
-
- CB = cos(B);
- SB = sin(B);
- CH = cos(H);
- SH = sin(H);
- CP = cos(P);
- SP = sin(P);
-
- AM = CB * CH - SH * SP * SB;
- BM = -CB * SH - SP * CH * SB;
- CM = CP * SB;
- DM = SH * CP;
- EM = CP * CH;
- FM = SP;
- GM = -CH * SB - SH * SP * CB;
- HM = SH * SB - SP * CH * CB;
- IM = CP * CB;
- XV = - DD * CP * SH;
- YV = - DD * CP * CH;
- ZV = - DD * SP;
- for (Ec = 0; Ec < N; Ec++)
- {
- X = aaa[Ec][0] - XV;
- Y = aaa[Ec][1] - YV;
- Z = aaa[Ec][2] - ZV;
- X3 = AM * X + BM * Y + CM * Z;
- Y3 = DM * X + EM * Y + FM * Z;
- Z3 = GM * X + HM * Y + IM * Z;
- XX = round (10 * DD * X3 / Y3 + 200);
- YY = round (10 * DD * Z3 / Y3 + 200);
- if (cc[Ec] != 0)
- {
- /* draw a line */
- RGBForeColor (&white);
- if (abs(cc[Ec]) == 1) RGBForeColor (&red);
- if (abs(cc[Ec]) == 2) RGBForeColor (&green);
- if (abs(cc[Ec]) == 3) RGBForeColor (&blue);
- if (cc[Ec] < 0) MoveTo (XX, YY); /* draw a point */
- LineTo (XX, YY);
- }
- else
- /* move to starting point of line */
- MoveTo (XX, YY);
- }
- RGBForeColor (&black);
- }
-
- //************************************************************************
-
- void getuserfile (void)
- {
- SFTypeList types;
- StandardFileReply mySFR;
-
- /* get a file name */
- types[0] = 'TEXT';
- StandardGetFile (NULL, 1, types, &mySFR);
-
- if (mySFR.sfGood)
- {
- readfile (mySFR.sfFile.vRefNum, mySFR.sfFile.parID,
- mySFR.sfFile.name);
- }
- }
-
- //************************************************************************
-
- void readfile (short refnum, long parid, Str63 name)
- {
- FILE *points;
- int i, j;
- double max, maybe;
-
- SetWTitle ((WindowPtr)thewindow, name);
-
- PtoCstr((StringPtr) name);
- err = HSetVol (NULL, refnum, parid);
- if (err) died ("Could not Set Volume", err, 4);
-
- /* read points from the file */
- points = fopen ((char *)name, "r");
- if (points == NULL) died ("Can't Open File", 0, 5);
- N = 0;
- do
- {
- err = (fscanf(points, "%lf %lf %lf %d", &aaa[N][0], &aaa[N][1],
- &aaa[N][2], &cc[N]));
- if (err != EOF) N++;
- if (err != 4 && err != EOF)
- {
- fclose (points);
- died ("Error Reading File", err, 6);
- }
- if (N > MaxPoints)
- {
- fclose (points);
- died ("Too Many Lines in File", 0, 7);
- }
- }
- while (err != EOF);
- fclose (points);
-
- /* get maximum distance of points from origin */
- max = 0;
- for (i=0; i<N; i++)
- {
- maybe = sqrt(aaa[i][0]*aaa[i][0] + aaa[i][1]*aaa[i][1] +
- aaa[i][2]*aaa[i][2]);
- if (maybe > max) max = maybe;
- }
- if (max == 0) died ("All Points at Origin", 0, 8);
- /* scale the points */
- for (i=0; i<N; i++)
- for (j=0; j<3; j++)
- aaa[i][j] /= max/19;
-
- /* reset rotation angles */
- Xangle = 0;
- Yangle = 0;
- Zangle = 0;
-
- /* draw the picture to GWorld and screen */
- SetGWorld(drawWorldP, nil);
- PaintRect(&frameRect);
- rotate ();
- SetGWorld(saveWorld, saveDevice);
- ShowWindow ((WindowPtr)thewindow);
- }
-
- //************************************************************************
-
- void installAEhandlers (void)
- {
- /* install the required apple event handlers */
- AEEventHandlerUPP OPENae, QUITae, STARTae, PRINTae;
-
- /* must use these for PPC proc pointers */
- OPENae = NewAEEventHandlerProc ((ProcPtr) &openAE);
- QUITae = NewAEEventHandlerProc ((ProcPtr) &quitAE);
- STARTae = NewAEEventHandlerProc ((ProcPtr) &startAE);
- PRINTae = NewAEEventHandlerProc ((ProcPtr) &printAE);
-
- err = AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
- OPENae, 0, FALSE);
- if (err) died ("Error Installing OpenDoc Apple Event", err, 9);
-
- err = AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
- QUITae, 0, FALSE);
- if (err) died ("Error Installing QuitApp Apple Event", err, 10);
-
- err = AEInstallEventHandler (kCoreEventClass, kAEOpenApplication,
- STARTae, 0, FALSE);
- if (err) died ("Error Installing OpenApp Apple Event", err, 11);
-
- err = AEInstallEventHandler (kCoreEventClass, kAEPrintDocuments,
- PRINTae, 0, FALSE);
- if (err) died ("Error Installing PrintDoc Apple Event", err, 12);
- }
-
- //************************************************************************
-
- void DoHighLevelEvent (EventRecord *theEvent)
- {
- /* process high level events */
- err = AEProcessAppleEvent (theEvent);
- if (err) died ("Error Processing Apple Event", err, 13);
- }
-
- //************************************************************************
-
- pascal OSErr openAE (AppleEvent *theEvent, AppleEvent *reply, long refcon)
- {
- AEDescList docList;
- long n;
- AEKeyword keywd;
- DescType rtype;
- FSSpec myFSS;
- Size acsize;
-
- /* open document apple event */
- err = AEGetParamDesc (theEvent, keyDirectObject, typeAEList, &docList);
- if (err) died ("Error Processing Apple Event", err, 14);
-
- /* count number of document to be opened */
- err = AECountItems (&docList, &n);
- if (err) died ("Error Processing Apple Event", err, 15);
- if (n < 1) died ("No File for OpenDoc Apple Event", 0, 16);
-
- /* get FSS record of the first document only */
- err = AEGetNthPtr (&docList, 1, typeFSS, &keywd, &rtype,
- &myFSS, sizeof(myFSS), &acsize);
- if (err) died ("Error Processing Apple Event", err, 17);
-
- /* get rid of storage */
- err = AEDisposeDesc (&docList);
- if (err) died ("Error Processing Apple Event", err, 18);
-
- /* open the passed file */
- readfile (myFSS.vRefNum, myFSS.parID, myFSS.name);
-
- return noErr;
- }
-
- //************************************************************************
-
- pascal OSErr quitAE(AppleEvent *theEvent, AppleEvent *reply, long refcon)
- {
- /* quit apple event - set the done flag */
- done = true;
- return noErr;
- }
-
- //************************************************************************
-
- pascal OSErr printAE (AppleEvent *theEvent, AppleEvent *reply, long refcon)
- {
- /* print apple event not handled here */
- return errAEEventNotHandled;
- }
-
- //************************************************************************
-
- pascal OSErr startAE (AppleEvent *theEvent, AppleEvent *reply, long refcon)
- {
- /* startup apple event - ask for an input file */
- getuserfile();
- return noErr;
- }
-
- //************************************************************************
-
- void died (char desc[255], int code, int ref)
- {
- /* nasty error has occurred - report it and quit */
- int go;
- char a[50], b[50];
-
- CtoPstr (desc);
- NumToString (code, (StringPtr)a);
- NumToString (ref, (StringPtr)b);
- ParamText ((StringPtr)desc, (StringPtr)a, (StringPtr)b, NULL);
- go = Alert(129,NULL);
- ExitToShell();
- }
-
- //************************************************************************
-
-
-
-
-
-
-
-
-
-